package com.sinosoft.cloud.access.crypto;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 *
 * @author yangming
 */
public class AesUtil {


    /**
     * 加密过程
     *
     * @param content
     * @param key
     * @param charsetName
     * @return
     */
    public static String encode(String content, String key, String charsetName) {
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            IvParameterSpec iv = new IvParameterSpec("ABCHINA..ANIHCBA".getBytes());
            byte[] rawKey = key.getBytes("ASCII");
            SecretKeySpec skeySpec = new SecretKeySpec(rawKey, "AES");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);

            byte[] bytes = content.getBytes();

            int length1 = bytes.length;
            //补齐16的整数倍
            byte[] msg;
            if(length1%16 != 0){
                byte[] s1 = new byte[16-length1%16];
                byte arr1[] = (" ").getBytes("UTF-8");
                for(int j=0;j<s1.length;j++){
                    s1[j]=arr1[0];
                }
                // 将两个数组合并到一个
                msg = new byte[bytes.length + s1.length];
                System.arraycopy(bytes, 0, msg, 0, bytes.length);
                System.arraycopy(s1, 0, msg, bytes.length, s1.length);
            } else {
                msg = bytes;
            }

            byte[] encrypted = cipher.doFinal(msg);
            return byte2hex(encrypted);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 解密过程
     *
     * @param content
     * @param key
     * @param charsetName
     * @return
     */
    public static String decode(String content, String key, String charsetName) {
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            IvParameterSpec iv = new IvParameterSpec("ABCHINA..ANIHCBA".getBytes());
            byte[] rawKey = key.getBytes();
            SecretKeySpec skeySpec = new SecretKeySpec(rawKey, "AES");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
            byte[] bPack1 = hex2byte(content);
            byte[] encrypted = cipher.doFinal(bPack1);
            return new String(encrypted, charsetName);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    private static byte[] hex2byte(String hex) {
        if (hex == null) {
            return null;
        }
        int l = hex.length();
        if (l % 2 == 1) {
            return null;
        }
        byte[] bytes = new byte[l / 2];
        for (int i = 0; i != l / 2; i++) {
            bytes[i] = (byte) Integer.parseInt(hex.substring(i * 2, i * 2 + 2), 16);
        }
        return bytes;
    }

    private static String byte2hex(byte[] bytes) {
        String hs = "";
        String stmp = "";
        for (int i = 0; i < bytes.length; i++) {
            stmp = (Integer.toHexString(bytes[i] & 0XFF));
            if (stmp.length() == 1) {
                hs = hs + "0" + stmp;
            } else {
                hs = hs + stmp;
            }
        }
        return hs.toUpperCase();
    }

    public static void main(String[] args) {

        while (true) {
            String strCode = "CA4404208D0B6CB09F9FA383CB1EC875D7B4E709E6A71BDCF7AF2E8AD63DA4002C8B237D6DEC807DFEA5FFC45433F8F96F7A914FA901C23049D9DB0932BE04C8072A5FB1C196100008755AFFFEB1787254AE97DA7758AC1B0040032720B2146443651D065ECD1F2416128385345DB2299F96B13686EF8CCE99E500581A9B2576E7AD44311838CD1C467598133712938BF1CEAFE80587785480B62A20FD79B9A0E556DAE1BA52DD760D7AF6FF23B1EB45D78986BCA6A8B8DCB974036A34AA7E154503240A3F7902DB3B97B561C572C78BEA3F328261C0903353B3CB7B97CE1DEE1FA2342E8C97D92E6FB669C75A6B2EE5E0CE532D88EE197D271F4CB52F5F24019BB4494820481F9422C7603BD874A7568D5479A9B317F149670075FD7FD277AA790D2E79AA5C5060B14DFD3E71581F387C9976842DB8EB1B71B95542423203FF0583055B02584E0A9A1B5977B803EDC86801098177E56D0108E92D8DDDD0EE7B1F695C3015D00573910E9651656892B6747A3ADE3D6C19D9BAF23C0CE6FD696D93EB28BEA705C7E6D2E3A3005C80A82E38A8DC0F22ADE60B86F2F5F258DC157286365EDAC30B2ECEC9D726F148C57C6C0419529674E7F4C240A63482310E54D293A667793C6055F257B1B9C3E3B9C0A5BBC94F49F34903914A121B823D4DB30DD62CDCD1173D5F06CAE90FF5E99455B8A6C0C73B17E3306CFEC0C66987EF564E0C6A6672AF103AD28C5C3052C08786C423A5643D3F01471837F6068E7B98D280DF7476792BB9C8160826A3E5EFA9A4F4BAB5EAF8E5C054BDD6395FB7AB8D7436CC6D4E44E6DBC8E3CF50F7DB4AEF38F3671721B45DBB8A9419CBDD3A6FD41ABA27B5DD1D1D384EC9C4FDBB2809ED5696D27602DDAA7A4DFA690BAF1FE9D35955BD3632D6A5491F988AC906DA3C962709A8C3A14664CC9ADF8878360E8EEE27D72CDF0741E581FF5886D1F8FDB0AB77E6D2D0AC6587E68EE23E06D1FA1A970573B2B27DE0952231B4F8B726108C6476859C940FDD1090289ECE43515C6455B29B97B0E655DE07E13076D4A6FE590D17B8AA742EA51EA5E9C8D00F88ACFBC13ABA";
            String styKey = "dD5ZSg1ijCwF3GWG";
            long a = System.currentTimeMillis();
            String bytes = decode(strCode, styKey, "GBK");
            System.out.println(bytes);
            System.out.println("耗时：" + (System.currentTimeMillis() - a));
        }
    }

    protected static String getThreadKey(int mode) {
        return mode + ";" + Thread.currentThread().getName() + ":" + Thread.currentThread().getId();
    }
}
